#include "include/Pool.h"
#include "include/Singleton.h"
#include "include/Manager.h"

 Pool::Pool(std::size_t pool_size)
	: _next_io_service_index(0)
{
	for(std::size_t i = 0; i < pool_size; i++)
	{
		io_service_sptr io_service(new boost::asio::io_service);
		work_sptr work(new boost::asio::io_service::work(*io_service));
		_io_service.push_back(io_service);
		_work.push_back(work);
	}

	_control_io_service = io_service_sptr(new boost::asio::io_service);
	_control_work = work_sptr(new boost::asio::io_service::work(*_control_io_service));
}

void  Pool::Start()
{
	for(std::size_t i = 0; i < _io_service.size(); i++)
	{
		boost::shared_ptr<boost::thread> thread(new boost::thread(
			boost::bind(&boost::asio::io_service::run, _io_service[i])));

		_threads.push_back(thread);
	}

	_control_thread = thread_sptr(new boost::thread(boost::bind(&boost::asio::io_service::run, _control_io_service)));
#if 0
	boost::shared_ptr<boost::thread> thread(new boost::thread(
		boost::bind(&Manager::Run, &Singleton<Manager>::instance())));
	_threads.push_back(thread);
#endif
}

void  Pool::Join()
{
	for(std::size_t i = 0; i < _threads.size(); i++)
	{
		_threads[i]->join();
	}

	_control_thread->join();
}

void  Pool::Stop()
{
	for(std::size_t i = 0; i < _threads.size(); i++)
	{
		_io_service[i]->stop();
	}

	_control_io_service->stop();
}

boost::asio::io_service & Pool::GetIoService(int &id)
{
	boost::mutex::scoped_lock lock(_mtx);
	boost::asio::io_service &io_service = *_io_service[_next_io_service_index];

	id = _next_io_service_index;
	
	_next_io_service_index++;
	if(_next_io_service_index == _io_service.size())
	{
		_next_io_service_index = 0;
	}

	return io_service;
}

boost::asio::io_service & Pool::GetIoService()
{
	int id;
	
	return GetIoService(id);
}

boost::asio::io_service & Pool::GetControlService()
{
	return *_control_io_service;
}
